// 读取配置文件
package confs

import (
	"fmt"

	"github.com/spf13/viper"
)

/**
 * 配置文件读取组件
 *   1. 可以在结构初始化时设置一些默认值
 *   2. 配置的默认值会被配置文件的信息覆盖
 *   3. 变量为 map 地址时， 默认值中配置里没有的信息会被保留
 *   4. 变量为 struct 时， 配置里没有的信息会使用零值
 */
type Reader struct {
	*viper.Viper
}

/**
 * 可链式操作
 * 增加一个配置文件查询目录
 */
func (r *Reader) AddConfigPath(path string) *Reader {
	r.Viper.AddConfigPath(path)
	return r
}

/**
 * 可链式操作
 * 设置读取的文件名
 */
func (r *Reader) SetConfigName(name string) *Reader {
	r.Viper.SetConfigName(name)
	return r
}

/**
 * 可链式操作
 * 设置文件的解析类型
 */
func (r *Reader) SetConfigType(typ string) *Reader {
	r.Viper.SetConfigType(typ)
	return r
}

/**
 * 可链式操作
 * 设置文件的解析类型
 */
func (r *Reader) SetConfigFile(file string) *Reader {
	r.Viper.SetConfigFile(file)
	return r
}

/**
 * 读取配置信息到 Vars 中
 */
func (r *Reader) ReadTo(confs map[string]any) (map[string]any, error) {
	err := r.Viper.ReadInConfig()
	if err != nil {
		return nil, fmt.Errorf("读取配置文件失败: %#v", err)
	}

	for k, v := range confs {
		err := r.UnmarshalKey(k, v)
		if err != nil {
			return nil, fmt.Errorf("解析配置 %s 失败: %#v", k, err)
		}
	}
	return confs, nil
}

/**
 * 新建读取配置组件
 */
func New() *Reader {
	return &Reader{
		Viper: viper.New(),
	}
}
